﻿using System;
using System.Collections.Generic;
using System.Configuration;
using System.Drawing;
using System.Drawing.Drawing2D;
using System.Drawing.Imaging;
using System.IO;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Xml;
using WindowsLive.Writer.Api;

namespace wlwthumb
{
    
    [WriterPlugin("B17A98A1-8B20-43A9-B615-EFA9D608713B",
    "ZosoThumb",
    Description = "ZosoThumb",
    HasEditableOptions = true,
    Name = "ZosoThumb",
    //ImagePath = "zoso.ico",
    PublisherUrl = "http://www.codres.de")]
    [InsertableContentSource("ZosoThumb")]    
    public class WLWThumb : ContentSource
    {
       

        public override void EditOptions(IWin32Window dialogOwner)
        {

            ShowSettings(dialogOwner, Options);    
            
            //base.EditOptions(dialogOwner);
        }

        public static void ShowSettings(IWin32Window dialogOwner, IProperties Options)
        {
            Settings s = new Settings();

            int r = Options.GetInt("colorR", 255);
            int g = Options.GetInt("colorG", 255);
            int b = Options.GetInt("colorB", 255);

            s.colorDialog1.Color = Color.FromArgb(255, r, g, b);

            s.checkBox1.Checked = Options.GetBoolean("crop", true);
            s.textBox1.Text = Options.GetString("width", "100");
            s.textBox3.Text = Options.GetString("height", "100");
            s.textBox2.Text = Options.GetString("template", Settings.DefaultTemplate);

            if (s.ShowDialog(dialogOwner) == DialogResult.OK)
            {
                Options.SetString("width", s.textBox1.Text);
                Options.SetString("height", s.textBox3.Text);
                Options.SetString("template", s.textBox2.Text);
                Options.SetBoolean("crop", s.checkBox1.Checked);
                Options.SetInt("colorR", s.colorDialog1.Color.R);
                Options.SetInt("colorG", s.colorDialog1.Color.G);
                Options.SetInt("colorB", s.colorDialog1.Color.B);
            }
        }

        public override DialogResult CreateContent
            (IWin32Window dialogOwner, ref string content)
        {
            if (String.IsNullOrEmpty(content))
            {
                return GetThumbnailCode(Options, ref content);
            }
            else
            {
                return CSSCropSelection(Options, ref content);
            }

        }


        /// <summary>
        /// Method 1: Try to fix by using CSS Faux Crop
        /// </summary>
        /// <param name="Options"></param>
        /// <param name="content"></param>
        /// <returns></returns>
        public static DialogResult CSSCropSelection(IProperties Options, ref string content)
        {
            int myWidth = 100;
            int myHeight = 100;
            int.TryParse(Options.GetString("width", "100"), out myWidth);
            int.TryParse(Options.GetString("height", "100"), out myHeight);
            string myTemplate = Options.GetString("template", Settings.DefaultTemplate);

            int r1 = Options.GetInt("colorR", 255);
            int g1 = Options.GetInt("colorG", 255);
            int b1 = Options.GetInt("colorB", 255);

            Color bkColor = Color.FromArgb(255, r1, g1, b1);

            bool isCrop = Options.GetBoolean("crop", true);


            // Parse content
            //<P><A 
            //href="file:///C:/Users/deCoder/AppData/Local/Temp/WindowsLiveWriter20212415/supfiles48B5039/tmp99DB[2].gif"><IMG 
            //title=tmp99DB style="DISPLAY: inline" alt=tmp99DB 
            //src="file:///C:/Users/deCoder/AppData/Local/Temp/WindowsLiveWriter20212415/supfiles48B5039/tmp99DB_thumb.gif" 
            //width=100 height=51></A>&nbsp;</P>

            string srcUri = null;
            string srcThumb = null;

            int thumbFilePos = -1;
            int thumbFileWidth = -1;

            int pHref = content.ToLower().IndexOf("href=\"");

            if (pHref >= 0)
            {
                string line = content.Substring(pHref + 6);

                int pQuotes = line.IndexOf("\"");

                srcUri = line.Substring(0, pQuotes);
            }

            int pSrc = content.ToLower().IndexOf("src=\"");

            if (pSrc >= 0)
            {
                string line = content.Substring(pSrc + 5);

                thumbFilePos = pSrc + 5;

                int pQuotes = line.IndexOf("\"");

                thumbFileWidth = pQuotes;

                srcThumb = line.Substring(0, pQuotes);
            }

            string sourceFileName = null;
            string thumbFileName = null;

            // Get the source img

            if (srcUri != null)
            {
                Uri uriSrc = new Uri(srcUri);
                if (uriSrc.IsFile)
                {
                    sourceFileName = uriSrc.LocalPath;
                }
            }

            // Get the thumb
            if (srcThumb != null)
            {
                Uri uriThumb = new Uri(srcThumb);
                if (uriThumb.IsFile)
                {
                    thumbFileName = uriThumb.LocalPath;
                }
            }

            Image img = null;

            string fileName = null;
            string ext = null;

            if (sourceFileName != null)
            {
                // Get the original and remake the thumb
                img = Image.FromFile(sourceFileName);
                fileName = sourceFileName;
            }
            else
                // Fix the thumb itself
                if (thumbFileName != null)
                {
                    img = Image.FromFile(thumbFileName);
                    fileName = thumbFileName;
                }

            if (img == null)
            {
                return GetThumbnailCode(Options, ref content);
            }

            int w = img.Width;
            int h = img.Height;

            int origW = img.Width;
            int origH = img.Height;

            int shiftH = 0;
            int shiftW = 0;

            double aspect = (double)img.Height / (double)img.Width;

            if (aspect<1D)
            {
                //[==] landscape                
                w = (int)((double)myWidth / aspect);
                h = myHeight;
                shiftH = 0;
                shiftW = w / 2 - myWidth / 2;

            }
            else
            {
                w = myWidth;
                h = (int)((double)myHeight / aspect);
                shiftH = h / 2 - myHeight/ 2;
                shiftW = 0;
            }


            CropForm c = new CropForm();
            c.MakeSelection(myWidth,myHeight,Image.FromFile(fileName));
            
            //c.ShowDialog();
            
            // calculate the div
            StringBuilder sb = new StringBuilder();

            //<div style="width: 100px; height: 100px; overflow: hidden;"><a href="http://www.codres.de/wordpress/wp-content/uploads/2013/01/tmpE9DF1.gif"><img class="alignleft size-full wp-image-2112" style="width: 200px; height: 100px; margin: -0px -0px -0px -50px;" title="tmpE9DF" src="http://www.codres.de/wordpress/wp-content/uploads/2013/01/tmpE9DF1.gif" alt="" /></a></div>            
            sb.AppendFormat("<div style='width:{0}px; height:{1}px; overflow: hidden; FLOAT: left;'>", myWidth, myHeight);
            sb.AppendFormat("<a href='{0}'>", srcUri);
            sb.AppendFormat("<img style='width: {0}px; height: {1}px; margin: -{2}px -{3}px -{4}px -{5}px;' src='{6}'/>", 
                w, //0
                h, //1
                shiftH, //2
                0, //3
                0, //4
                shiftW, //5
                srcThumb //6
                );
            sb.AppendFormat("</a></div>");

            content = sb.ToString();

            return DialogResult.OK;
        }


        /// <summary>
        /// Method 2: Try to fix by correcting the thumbnail on the temp folder (very unrealiable)
        /// </summary>
        /// <param name="Options"></param>
        /// <param name="content"></param>
        /// <returns></returns>
        public static DialogResult FixThumbnailCode(IProperties Options, ref string content)
        {
            int myWidth = 100;
            int myHeight = 100;
            int.TryParse(Options.GetString("width", "100"), out myWidth);
            int.TryParse(Options.GetString("height", "100"), out myHeight);
            string myTemplate = Options.GetString("template", Settings.DefaultTemplate);

            int r1 = Options.GetInt("colorR", 255);
            int g1 = Options.GetInt("colorG", 255);
            int b1 = Options.GetInt("colorB", 255);

            Color bkColor = Color.FromArgb(255, r1, g1, b1);

            bool isCrop = Options.GetBoolean("crop", true);           


            // Parse content
            //<P><A 
            //href="file:///C:/Users/deCoder/AppData/Local/Temp/WindowsLiveWriter20212415/supfiles48B5039/tmp99DB[2].gif"><IMG 
            //title=tmp99DB style="DISPLAY: inline" alt=tmp99DB 
            //src="file:///C:/Users/deCoder/AppData/Local/Temp/WindowsLiveWriter20212415/supfiles48B5039/tmp99DB_thumb.gif" 
            //width=100 height=51></A>&nbsp;</P>

            string srcUri = null;
            string srcThumb = null;

            int thumbFilePos = -1;
            int thumbFileWidth = -1;

            int pHref = content.ToLower().IndexOf("href=\"");

            if (pHref >= 0)
            {
                string line = content.Substring(pHref + 6);

                int pQuotes = line.IndexOf("\"");

                srcUri = line.Substring(0, pQuotes);
            }

            int pSrc = content.ToLower().IndexOf("src=\"");

            if (pSrc >= 0)
            {
                string line = content.Substring(pSrc + 5);

                thumbFilePos = pSrc + 5;

                int pQuotes = line.IndexOf("\"");

                thumbFileWidth = pQuotes;

                srcThumb = line.Substring(0, pQuotes);
            }

            string sourceFileName = null;
            string thumbFileName = null;

            // Get the source img

            if (srcUri != null)
            {
                Uri uriSrc = new Uri(srcUri);
                if (uriSrc.IsFile)
                {
                    sourceFileName = uriSrc.LocalPath;
                }
            }

            // Get the thumb
            if (srcThumb != null)
            {
                Uri uriThumb = new Uri(srcThumb);
                if (uriThumb.IsFile)
                {
                    thumbFileName = uriThumb.LocalPath;
                }
            }

            Image img = null;

            string fileName = null;
            string ext = null;

            if (sourceFileName != null)
            {
                // Get the original and remake the thumb
                img = Image.FromFile(sourceFileName);
                fileName = sourceFileName;                
            }
            else            
                // Fix the thumb itself
                if (thumbFileName != null)
                {
                    img = Image.FromFile(thumbFileName);
                    fileName = thumbFileName;
                }
            
            

            if (img == null)
            {
                return GetThumbnailCode(Options, ref content);
            }

            ext = Path.GetExtension(fileName).ToLower();            

            int w = img.Width;// Properties.Settings.Default.Width;
            int h = img.Height;// Properties.Settings.Default.Height;

            int commonSize = w;

            Rectangle r = new Rectangle(0, 0, w, h);

            if (img.Width > img.Height)
            {
                //[==]
                r = new Rectangle(w / 2 - h / 2, 0, h, h);
                commonSize = h;

            }
            else
            {
                //[]
                r = new Rectangle(0, h / 2 - w / 2, w, w);
                commonSize = w;
            }

            w = myWidth;
            h = myHeight;

            Image outImg = null;

            if (isCrop)
            {
                outImg = new Bitmap(w, h);

                using (Graphics g = Graphics.FromImage(outImg))
                {
                    g.DrawImage(img, new Rectangle(0, 0, w, h),
                                     r,
                                     GraphicsUnit.Pixel);
                }
            }
            else
            {
                outImg = FixedSize(img, w, h, bkColor, InterpolationMode.HighQualityBilinear);
            }

            if (File.Exists(fileName))
            {
                // Change FileName
                fileName = Path.Combine(Path.GetDirectoryName(fileName),Path.GetFileNameWithoutExtension(fileName)+"_tmp");
                fileName = fileName + ext;

                // replace content thumb fileName

                string newContent = content;

                Uri tempUri = new Uri(fileName);

                newContent = newContent.Remove(thumbFilePos, thumbFileWidth);
                newContent = newContent.Insert(thumbFilePos, tempUri.AbsoluteUri);

                content = newContent;

            }

            if (ext == ".png")                
                {
                    outImg.Save(fileName, ImageFormat.Png);                    
                } else

                    if (ext == ".gif")
                    {
                        outImg.Save(fileName, ImageFormat.Gif);

                    }
                    else
                    {
                        ImageCodecInfo jgpEncoder = GetEncoder(ImageFormat.Jpeg);
                        System.Drawing.Imaging.Encoder myEncoder = System.Drawing.Imaging.Encoder.Quality;
                        EncoderParameters myEncoderParameters = new EncoderParameters(1);
                        EncoderParameter myEncoderParameter = new EncoderParameter(myEncoder, 80L);
                        myEncoderParameters.Param[0] = myEncoderParameter;
                        outImg.Save(fileName, jgpEncoder, myEncoderParameters);
                    }
            

            return DialogResult.OK;
        }

        /// <summary>
        /// Create a thumbnail from a selected image and generated the html code for it.
        /// Problems when introducing "a href"... Apparently WLW removes it.
        /// </summary>
        /// <param name="Options"></param>
        /// <param name="content"></param>
        /// <returns></returns>
        public static DialogResult GetThumbnailCode(IProperties Options, ref string content)
        {
            int myWidth = 100;
            int myHeight = 100;
            int.TryParse(Options.GetString("width", "100"), out myWidth);
            int.TryParse(Options.GetString("height", "100"), out myHeight);
            string myTemplate = Options.GetString("template", Settings.DefaultTemplate);

            int r1 = Options.GetInt("colorR", 255);
            int g1 = Options.GetInt("colorG", 255);
            int b1 = Options.GetInt("colorB", 255);

            Color bkColor = Color.FromArgb(255, r1, g1, b1);

            bool isCrop = Options.GetBoolean("crop", true);

            OpenFileDialog fd = new OpenFileDialog();
            fd.Filter = "All Files|*.jpg;*.jpeg;*.png;*.gif;*.bmp";
            if (fd.ShowDialog() == DialogResult.OK)
            {
                string fullPath = System.Reflection.Assembly.GetAssembly(typeof(WLWThumb)).Location;

                //get the folder that's in
                string theDirectory = Path.GetDirectoryName(fullPath);

                string ext = Path.GetExtension(fd.FileName).ToLower();

                Image img = Image.FromFile(fd.FileName);

                int w = img.Width;// Properties.Settings.Default.Width;
                int h = img.Height;// Properties.Settings.Default.Height;

                int commonSize = w;

                Rectangle r = new Rectangle(0, 0, w, h);

                if (img.Width > img.Height)
                {
                    //[==]
                    r = new Rectangle(w / 2 - h / 2, 0, h, h);
                    commonSize = h;

                }
                else
                {
                    //[]
                    r = new Rectangle(0, h / 2 - w / 2, w, w);
                    commonSize = w;
                }

                w = myWidth;
                h = myHeight;

                Image outImg = null;

                if (isCrop)
                {
                    outImg = new Bitmap(w, h);

                    using (Graphics g = Graphics.FromImage(outImg))
                    {
                        g.DrawImage(img, new Rectangle(0, 0, w, h),
                                         r,
                                         GraphicsUnit.Pixel);
                    }
                }
                else
                {
                    outImg = FixedSize(img, w, h, bkColor, InterpolationMode.HighQualityBilinear);
                }

                string fileName = fd.FileName;
                string name = Path.GetFileNameWithoutExtension(fileName);

                //HKEY_CURRENT_USER\Software\Microsoft\Windows Live\Writer

                //string lTemp = "WindowsLiveWriter20212415\\supfiles48B5039\\";
                string lTemp = "";

                string outFileName = System.IO.Path.GetTempPath() + lTemp + name + ext;
                string thumbFileName = System.IO.Path.GetTempPath() + lTemp + name + "_thumb" + ext;


                if ((ext == ".png") || (ext == ".gif"))
                //if (ext == ".png")
                {
                    img.Save(outFileName, ImageFormat.Png);
                    outImg.Save(thumbFileName, ImageFormat.Png);
                }
                else
                //if (ext == ".gif")
                //{
                //    ImageCodecInfo gifEncoder = GetEncoder(ImageFormat.Gif);
                //    EncoderParameter encCompressionrParameter = new EncoderParameter(System.Drawing.Imaging.Encoder.Compression, (long)EncoderValue.CompressionLZW);
                //    EncoderParameter p2 = new EncoderParameter(System.Drawing.Imaging.Encoder.ColorDepth, 8L);
                //    EncoderParameter p3 = new EncoderParameter(System.Drawing.Imaging.Encoder.Version, (long)EncoderValue.VersionGif89);
                //    EncoderParameter encQualityParameter = new EncoderParameter(System.Drawing.Imaging.Encoder.Quality, 0L);
                //    EncoderParameters myEncoderParameters = new EncoderParameters(4);
                //    myEncoderParameters.Param[0] = encCompressionrParameter;
                //    myEncoderParameters.Param[1] = encQualityParameter;
                //    myEncoderParameters.Param[2] = p2;
                //    myEncoderParameters.Param[3] = p3;

                //    img.Save(outFileName, gifEncoder, myEncoderParameters);
                //    outImg.Save(thumbFileName, gifEncoder, myEncoderParameters);
                //}
                //else
                {
                    ImageCodecInfo jgpEncoder = GetEncoder(ImageFormat.Jpeg);
                    System.Drawing.Imaging.Encoder myEncoder = System.Drawing.Imaging.Encoder.Quality;
                    EncoderParameters myEncoderParameters = new EncoderParameters(1);
                    EncoderParameter myEncoderParameter = new EncoderParameter(myEncoder, 80L);
                    myEncoderParameters.Param[0] = myEncoderParameter;
                    img.Save(outFileName, jgpEncoder, myEncoderParameters);
                    outImg.Save(thumbFileName, jgpEncoder, myEncoderParameters);
                }

                //MessageBox.Show(outFileName+"\r\n"+thumbFileName);

                //content = string.Format("<p><a href='{0}'><img title='{1}' style='FLOAT: left; DISPLAY: inline' alt='{1}' src='{2}' width={3} height={4}></a></p>", outFileName, name, thumbFileName, w, h);

                var uriOutFileName = new Uri(outFileName);
                var cOutFileName = uriOutFileName.AbsoluteUri;

                var uriThumbFileName = new Uri(thumbFileName);
                var cThumbFileName = uriThumbFileName.AbsoluteUri;

                var uriFileName = new Uri(fileName);
                var cFileName = uriFileName.AbsoluteUri;


                //content = string.Format("<a href=\"{0}\"><img title=\"{1}\" style=\"FLOAT: left; DISPLAY: inline\" alt=\"{1}\" src=\"{2}\"></a>", cOutFileName, name, cThumbFileName);
                //content = string.Format("<a href='{0}'><img title='{1}' style='FLOAT: left; DISPLAY: inline' alt='{1}' src='{2}'></a>", cOutFileName, name, cThumbFileName);
                content = string.Format(myTemplate, name, cThumbFileName, cFileName, w, h);

                // content = string.Format("<p><a href='{0}'><img title='{1}' style='float: left; display ' alt='{1}' src='{2}' width={3} height={4}></a></p>", outFileName, name, thumbFileName, w, h);
                return DialogResult.OK;
            }
            else
            {

                return DialogResult.Cancel;
            }
        }

        public static ImageCodecInfo GetEncoder(ImageFormat format)
        {

            ImageCodecInfo[] codecs = ImageCodecInfo.GetImageDecoders();

            foreach (ImageCodecInfo codec in codecs)
            {
                if (codec.FormatID == format.Guid)
                {
                    return codec;
                }
            }
            return null;
        }

        private static ImageCodecInfo GetEncoderInfo(String mimeType)
        {
            int j;
            ImageCodecInfo[] encoders;
            encoders = ImageCodecInfo.GetImageEncoders();
            for (j = 0; j < encoders.Length; ++j)
            {
                if (encoders[j].MimeType == mimeType)
                    return encoders[j];
            }
            return null;
        }


        public static System.Drawing.Image FixedSize(System.Drawing.Image imgPhoto, int Width, int Height, Color backColor, InterpolationMode mode)
        {
            if ((Width == 0) || (Height == 0)) return null;

            int sourceWidth = imgPhoto.Width;
            int sourceHeight = imgPhoto.Height;
            int sourceX = 0;
            int sourceY = 0;
            int destX = 0;
            int destY = 0;

            float nPercent = 0;
            float nPercentW = 0;
            float nPercentH = 0;

            nPercentW = ((float)Width / (float)sourceWidth);
            nPercentH = ((float)Height / (float)sourceHeight);
            if (nPercentH < nPercentW)
            {
                nPercent = nPercentH;
                destX = System.Convert.ToInt16((Width -
                              (sourceWidth * nPercent)) / 2);
            }
            else
            {
                nPercent = nPercentW;
                destY = System.Convert.ToInt16((Height -
                              (sourceHeight * nPercent)) / 2);
            }

            int destWidth = (int)(sourceWidth * nPercent);
            int destHeight = (int)(sourceHeight * nPercent);

            Bitmap bmPhoto = new Bitmap(Width, Height,
                              PixelFormat.Format24bppRgb);

            bmPhoto.SetResolution(imgPhoto.HorizontalResolution,
                             imgPhoto.VerticalResolution);

            Graphics grPhoto = Graphics.FromImage(bmPhoto);

            grPhoto.Clear(backColor);

            grPhoto.InterpolationMode = mode;
            //InterpolationMode.HighQualityBicubic;

            grPhoto.DrawImage(imgPhoto,
                new Rectangle(destX, destY, destWidth + 1, destHeight),
                new Rectangle(sourceX, sourceY + 1, sourceWidth, sourceHeight - 1),
                GraphicsUnit.Pixel);

            grPhoto.Dispose();
            return bmPhoto;
        }
    }
}
